/*
 * 标签, 一般用于显示字串, 没有事件, 也没有图片
 */

#include "gui.h"
#include <stdlib.h>
#include <string.h>

#define TEXT_MAX	65536
#define LINE_MAX	4096

void input_update_buf(struct Input *ip)
{
	char *txt = ip -> _text;
	int line = 0;
	for (line = 0; line < ip -> _disp_line && *txt; txt++) {
		if (*txt == '\n') line++;
	}
	if (line < ip -> _disp_line) ip -> _disp_line = line;
	if (*txt == 0) txt = " ";
	
	char linebuf[LINE_MAX];
	int i = 0, j = 0;
	int y = 0;
	int dy = 15;
	Image a;
	
	video_set_screen(ip -> _img_buf);
	video_set_color(0, 0, 0);
	
	video_bar(0, 0, img_get_width(ip -> _img_buf),
		  img_get_height(ip -> _img_buf));
	video_drawimg(gui_get_box_bg(), 0, 0);
	
	while (1) {
		i = 0;
		while(txt[j]) {
			linebuf[i] = txt[j];
			if (j == ip -> _cursor) {
				char tmp = linebuf[i];
				linebuf[i] = 0;
				a = ttf_make_img(ip -> _font, linebuf, ip -> _font_color);
				dy = img_get_height(a);
				video_set_color(255, 255, 255);
				video_line(img_get_width(a), y, 
					   img_get_width(a), y + dy);
				video_destory_img(a);
				linebuf[i] = tmp;
			}
			if (linebuf[i] == '\n') {
				linebuf[i] = 0;
				j++;
				break;
			}
			i++;
			j++;
		}
		linebuf[i] = 0;
		
		a = ttf_make_img(ip -> _font, linebuf, ip -> _font_color);
		video_drawimg(a, 0, y);
		dy = img_get_height(a);
		y += dy;
		video_destory_img(a);
		
		if (txt[j] == 0) break;
	}
	video_reset_screen();
}

void ACALLBACK __input_render(struct Area *who,
			       void *userdata)
{
	struct Input *ip = (struct Input *) userdata;
	int x, y;
	x = who -> _x;
	y = who -> _y;
	
	if (ip -> _need_update) {
		input_update_buf(ip);
		ip -> _need_update = 0;
	}
	
	if (ip -> _img_buf) {
		video_drawimg(ip -> _img_buf, x, y);
	}
	video_set_color(0, 0, 0);
	video_rectangle(x, y, x + who -> _width, y + who -> _height);
}

void ACALLBACK __input_key_up(struct Area *who, int key, Uint32 unicode, void *userdata)
{

}

void ACALLBACK __input_key_down(struct Area *who, int key, Uint32 unicode, void *userdata)
{
	struct Input *ip = (struct Input *) userdata;
	char ch = 0;
	if ((unicode & 0xFF80) == 0 ) {
		ch = unicode & 0x7F;
	}
	
	ip -> _need_update = 1;
		
	if (key == SDLK_LEFT) {
		ip -> _cursor--;
		if (ip -> _cursor < 0) ip -> _cursor = 0;
	} else if (key == SDLK_RIGHT) {
		ip -> _cursor++;
		if (ip -> _cursor > strlen(ip -> _text)) ip -> _cursor = strlen(ip -> _text);
	} else if (key == SDLK_DELETE) {
		input_del(ip);
		return;
	}
	switch (ch) {
		case 13:	//return 
			input_input(ip, "\n");
			break;
		case 8:		//backspace
			input_back(ip);
			break;
		default:
			if (ch >= 32) {
				char a[2];
				a[0] = ch;
				a[1] = 0;
				input_input(ip, a);
			}
	}
}


	
void input_input(struct Input *ip, const char *str)
{
	//printf("[%s]\n", ip -> _text);
	int len = strlen(str);
	int i;
	for (i = strlen(ip -> _text); i >= ip -> _cursor; --i) {
		if (i + len < TEXT_MAX)
			ip -> _text[i + len] = ip -> _text[i];
	}
	memcpy(ip -> _text + ip -> _cursor, str, strlen(str));
	ip -> _cursor += len;
	//printf("[%s]\n", ip -> _text);
}

void input_del(struct Input *ip)
{
	int i;
	if (ip -> _cursor >= strlen(ip -> _text)) return ;
	
	for (i = ip -> _cursor; i < strlen(ip -> _text); ++i)
		ip -> _text[i] = ip -> _text[i + 1];
}

void input_back(struct Input *ip)
{
	int i;
	if (ip -> _cursor <= 0) return;
	for (i = ip -> _cursor; i < strlen(ip -> _text); ++i)
		ip -> _text[i - 1] = ip -> _text[i];
	ip -> _text[i - 1] = 0;
	ip -> _cursor --;
	if (ip -> _cursor < 0) ip -> _cursor = 0;
}

void input_set_cur(struct Input *ip, int cur)
{
	if (cur < 0) cur = strlen(ip -> _text);
	if (cur > strlen(ip -> _text)) cur = strlen(ip -> _text);
	ip -> _cursor = cur;
	ip -> _need_update = 1;
}


struct Input *input_new(struct Panel *father, int x, int y,
			  int width, int height)
{
	struct Input *ret;
	ret = malloc(sizeof(struct Input));
	memset(ret, 0, sizeof(struct Input));
	
	struct Area *a;
	int xx, yy;
	if (father) {		//换成绝对坐标
		a = father -> _area;
		xx = father -> _area -> _x + x;
		yy = father -> _area -> _y + y;
	} else {
		a = NULL;
		xx = x;
		yy = y;
	}
	ret -> _area = area_new(a, xx, yy, width, height);
	ret -> _area -> enable = 1;
	ret -> _area -> visual = 1;
	ret -> _area -> userdata = ret;
	
	ret -> _area -> user_render = __input_render;
	ret -> _area -> key_up = __input_key_up;
	ret -> _area -> key_down = __input_key_down;
	
	ret -> _font = gui_get_font_small();
	ret -> _font_color = 0xffffff;
	
	ret -> _text = malloc(TEXT_MAX * sizeof(char));
	ret -> _text[0] = 0;
	
	ret -> _img_buf = video_create_image(width, height);
	video_set_alpha(ret -> _img_buf, 156);
	ret -> _need_update = 1;
	
	return ret;
}

void input_set_font(struct Input *ip, Font font)
{
	ip -> _font = font;
}


void input_delete(struct Input *ip)
{
	ip -> _area -> enable = 0;
	ip -> _area -> visual = 0;
	if (ip -> _text) free(ip -> _text);
	if (ip -> _img_buf) video_destory_img(ip -> _img_buf);
	free(ip);
}

void input_set_color(struct Input *ip, Uint32 color)
{
	ip -> _font_color = color;
}

void input_set_align(struct Input *ip, int align)
{
	ip -> _align = align;
}
